home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''A very experimental approach to the refreshable Braille display. This
- module treats each line of the display as a sequential set of regions, where
- each region can potentially backed by an Accessible object. Depending upon
- the Accessible object, the cursor routing keys can be used to perform
- operations on the Accessible object, such as invoking default actions or
- moving the text caret.
- '''
- __id__ = '$Id: braille.py 4311 2008-10-30 12:50:03Z wwalker $'
- __version__ = '$Revision: 4311 $'
- __date__ = '$Date: 2008-10-30 08:50:03 -0400 (Thu, 30 Oct 2008) $'
- __copyright__ = 'Copyright (c) 2005-2008 Sun Microsystems Inc.'
- __license__ = 'LGPL'
- import logging
- log = logging.getLogger('braille')
- import signal
-
- try:
- import louis
- except ImportError:
- louis = None
- _defaultContractionTable = None
-
- _defaultContractionTable = louis.getDefaultTable()
-
- try:
- import brlapi
- import gobject
- brlAPI = None
- useBrlAPIBindings = True
- brlAPIRunning = False
- brlAPISourceId = 0
- except:
- import brl
- useBrlAPIBindings = False
- brlAPIRunning = False
-
-
- try:
- import brlmon
- except:
- pass
-
- import debug
- import eventsynthesizer
- import orca_state
- import settings
- from orca_i18n import _
- _initialized = False
- monitor = None
- CMD_NOOP = 0
- CMD_LNUP = 1
- CMD_LNDN = 2
- CMD_WINUP = 3
- CMD_WINDN = 4
- CMD_PRDIFLN = 5
- CMD_NXDIFLN = 6
- CMD_ATTRUP = 7
- CMD_ATTRDN = 8
- CMD_TOP = 9
- CMD_BOT = 10
- CMD_TOP_LEFT = 11
- CMD_BOT_LEFT = 12
- CMD_PRPGRPH = 13
- CMD_NXPGRPH = 14
- CMD_PRPROMPT = 15
- CMD_NXPROMPT = 16
- CMD_PRSEARCH = 17
- CMD_NXSEARCH = 18
- CMD_CHRLT = 19
- CMD_CHRRT = 20
- CMD_HWINLT = 21
- CMD_HWINRT = 22
- CMD_FWINLT = 23
- CMD_FWINRT = 24
- CMD_FWINLTSKIP = 25
- CMD_FWINRTSKIP = 26
- CMD_LNBEG = 27
- CMD_LNEND = 28
- CMD_HOME = 29
- CMD_BACK = 30
- CMD_FREEZE = 31
- CMD_DISPMD = 32
- CMD_SIXDOTS = 33
- CMD_SLIDEWIN = 34
- CMD_SKPIDLNS = 35
- CMD_SKPBLNKWINS = 36
- CMD_CSRVIS = 37
- CMD_CSRHIDE = 38
- CMD_CSRTRK = 39
- CMD_CSRSIZE = 40
- CMD_CSRBLINK = 41
- CMD_ATTRVIS = 42
- CMD_ATTRBLINK = 43
- CMD_CAPBLINK = 44
- CMD_TUNES = 45
- CMD_HELP = 46
- CMD_INFO = 47
- CMD_LEARN = 48
- CMD_PREFMENU = 49
- CMD_PREFSAVE = 50
- CMD_PREFLOAD = 51
- CMD_MENU_FIRST_ITEM = 52
- CMD_MENU_LAST_ITEM = 53
- CMD_MENU_PREV_ITEM = 54
- CMD_MENU_NEXT_ITEM = 55
- CMD_MENU_PREV_SETTING = 56
- CMD_MENU_NEXT_SETTING = 57
- CMD_SAY_LINE = 58
- CMD_SAY_ABOVE = 59
- CMD_SAY_BELOW = 60
- CMD_MUTE = 61
- CMD_SPKHOME = 62
- CMD_SWITCHVT_PREV = 63
- CMD_SWITCHVT_NEXT = 64
- CMD_CSRJMP_VERT = 65
- CMD_PASTE = 66
- CMD_RESTARTBRL = 67
- CMD_RESTARTSPEECH = 68
- CMD_MAX = 68
- BRL_FLG_REPEAT_INITIAL = 8388608
- BRL_FLG_REPEAT_DELAY = 4194304
- command_name = { }
- command_name[CMD_FWINLT] = _('Line Left')
- command_name[CMD_FWINRT] = _('Line Right')
- command_name[CMD_LNUP] = _('Line Up')
- command_name[CMD_LNDN] = _('Line Down')
- command_name[CMD_FREEZE] = _('Freeze')
- command_name[CMD_TOP_LEFT] = _('Top Left')
- command_name[CMD_BOT_LEFT] = _('Bottom Right')
- command_name[CMD_HOME] = _('Cursor Position')
- _displaySize = [
- 32,
- 1]
- _lines = []
- _regionWithFocus = None
- viewport = [
- 0,
- 0]
- _callback = None
- endIsShowing = False
- beginningIsShowing = False
- cursorCell = 0
-
- def _printBrailleEvent(level, command):
- '''Prints out a Braille event. The given level may be overridden
- if the eventDebugLevel (see debug.setEventDebugLevel) is greater in
- debug.py.
-
- Arguments:
- - command: the BrlAPI command for the key that was pressed.
- '''
- debug.printInputEvent(level, 'BRAILLE EVENT: %x' % command)
-
-
- class Region:
- '''A Braille region to be displayed on the display. The width of
- each region is determined by its string.
- '''
-
- def __init__(self, string, cursorOffset = 0, expandOnCursor = False):
- '''Creates a new Region containing the given string.
-
- Arguments:
- - string: the string to be displayed
- - cursorOffset: a 0-based index saying where to draw the cursor
- for this Region if it gets focus.
- '''
- if not string:
- string = ''
-
- if settings.enableContractedBraille:
- pass
- self.contracted = louis is not None
- self.expandOnCursor = expandOnCursor
- self.rawLine = string.decode('UTF-8').strip('\n')
- if self.contracted:
- if not settings.brailleContractionTable:
- pass
- self.contractionTable = _defaultContractionTable
- (self.string, self.inPos, self.outPos, self.cursorOffset) = self.contractLine(self.rawLine, cursorOffset, expandOnCursor)
- else:
- self.string = self.rawLine
- self.cursorOffset = cursorOffset
-
-
- def processRoutingKey(self, offset):
- '''Processes a cursor routing key press on this Component. The offset
- is 0-based, where 0 represents the leftmost character of string
- associated with this region. Note that the zeroeth character may have
- been scrolled off the display.'''
- pass
-
-
- def getAttributeMask(self, getLinkMask = True):
- """Creates a string which can be used as the attrOr field of brltty's
- write structure for the purpose of indicating text attributes, links,
- and selection.
-
- Arguments:
- - getLinkMask: Whether or not we should take the time to get
- the attributeMask for links. Reasons we might not want to
- include knowning that we will fail and/or it taking an
- unreasonable amount of time (AKA Gecko).
- """
- maskSize = len(self.string) + 2 * self.string.count(u'…')
- mask = [
- '\x00'] * maskSize
- return ''.join(mask)
-
-
- def repositionCursor(self):
- '''Reposition the cursor offset for contracted mode.
- '''
- if self.contracted:
- (self.string, self.inPos, self.outPos, self.cursorOffset) = self.contractLine(self.rawLine, self.cursorOffset, self.expandOnCursor)
-
-
-
- def contractLine(self, line, cursorOffset = 0, expandOnCursor = False):
- '''Contract the given line. Returns the contracted line, and the
- cursor position in the contracted line.
-
- Arguments:
- - line: Line to contract.
- - cursorOffset: Offset of cursor,defaults to 0.
- - expandOnCursor: Expand word under cursor, False by default.
- '''
-
- try:
- cursorOnSpace = line[cursorOffset] == ' '
- except IndexError:
- cursorOnSpace = False
-
- if not expandOnCursor or cursorOnSpace:
- (contracted, inPos, outPos, cursorPos) = louis.translate([
- self.contractionTable], line, cursorPos = cursorOffset)
- else:
- (contracted, inPos, outPos, cursorPos) = louis.translate([
- self.contractionTable], line, cursorPos = cursorOffset, mode = louis.MODE.compbrlAtCursor)
- return (contracted, inPos, outPos, cursorPos)
-
-
- def displayToBufferOffset(self, display_offset):
-
- try:
- offset = self.inPos[display_offset]
- except IndexError:
- offset = len(self.rawLine)
- except AttributeError:
- offset = display_offset
-
- return offset
-
-
- def setContractedBraille(self, contracted):
- if self.contracted == contracted:
- return None
- self.contracted = contracted
- if contracted:
- if not settings.brailleContractionTable:
- pass
- self.contractionTable = _defaultContractionTable
- self.contractRegion()
- else:
- self.expandRegion()
-
-
- def contractRegion(self):
- (self.string, self.inPos, self.outPos, self.cursorOffset) = self.contractLine(self.rawLine, self.cursorOffset, self.expandOnCursor)
-
-
- def expandRegion(self):
- if not self.contracted:
- return None
- self.string = self.rawLine
-
- try:
- self.cursorOffset = self.inPos[self.cursorOffset]
- except IndexError:
- self.contracted
- self.contracted
- self.cursorOffset = len(self.string)
- except:
- self.contracted
-
-
-
-
- class Component(Region):
- '''A subclass of Region backed by an accessible. This Region will react
- to any cursor routing key events and perform the default action on the
- accessible, if a default action exists.
- '''
-
- def __init__(self, accessible, string, cursorOffset = 0, indicator = '', expandOnCursor = False):
- '''Creates a new Component.
-
- Arguments:
- - accessible: the accessible
- - string: the string to use to represent the component
- - cursorOffset: a 0-based index saying where to draw the cursor
- for this Region if it gets focus.
- '''
- Region.__init__(self, string, cursorOffset, expandOnCursor)
- if indicator:
- if self.string:
- self.string = indicator + ' ' + self.string
- else:
- self.string = indicator
-
- self.accessible = accessible
-
-
- def processRoutingKey(self, offset):
- '''Processes a cursor routing key press on this Component. The offset
- is 0-based, where 0 represents the leftmost character of string
- associated with this region. Note that the zeroeth character may have
- been scrolled off the display.'''
-
- try:
- action = self.accessible.queryAction()
- except:
- debug.println(debug.LEVEL_FINEST, 'braille.Component.processRoutingKey: no action')
-
- try:
- eventsynthesizer.clickObject(self.accessible, 1)
- debug.printException(debug.LEVEL_SEVERE)
-
-
- action.doAction(0)
-
-
-
- class Link(Component):
- """A subclass of Component backed by an accessible. This Region will be
- marked as a link by dots 7 or 8, depending on the user's preferences.
- """
-
- def __init__(self, accessible, string, cursorOffset = 0):
- '''Initialize a Link region. similar to Component, but here we always
- have the region expand on cursor.'''
- Component.__init__(self, accessible, string, cursorOffset, '', True)
-
-
- def getAttributeMask(self, getLinkMask = True):
- """Creates a string which can be used as the attrOr field of brltty's
- write structure for the purpose of indicating text attributes and
- selection.
- Arguments:
-
- - getLinkMask: Whether or not we should take the time to get
- the attributeMask for links. Reasons we might not want to
- include knowning that we will fail and/or it taking an
- unreasonable amount of time (AKA Gecko).
- """
- return chr(settings.brailleLinkIndicator) * len(self.string)
-
-
-
- class Text(Region):
- '''A subclass of Region backed by a Text object. This Region will
- react to any cursor routing key events by positioning the caret in
- the associated text object. The line displayed will be the
- contents of the text object preceded by an optional label.
- [[[TODO: WDW - need to add in text selection capabilities. Logged
- as bugzilla bug 319754.]]]'''
-
- def __init__(self, accessible, label = '', eol = '', startOffset = None, endOffset = None):
- '''Creates a new Text region.
-
- Arguments:
- - accessible: the accessible that implements AccessibleText
- - label: an optional label to display
- '''
- self.accessible = accessible
- if orca_state.activeScript:
- (string, self.caretOffset, self.lineOffset) = orca_state.activeScript.getTextLineAtCaret(self.accessible, startOffset)
- else:
- string = ''
- string = string.decode('UTF-8')
- if label:
- label = label.decode('UTF-8')
-
- if eol:
- eol = eol.decode('UTF-8')
-
-
- try:
- endOffset = endOffset - self.lineOffset
- except TypeError:
- pass
-
-
- try:
- self.startOffset = startOffset - self.lineOffset
- except TypeError:
- self.startOffset = 0
-
- string = string[self.startOffset:endOffset]
- self.caretOffset -= self.startOffset
- cursorOffset = min(self.caretOffset - self.lineOffset, len(string))
- self._maxCaretOffset = self.lineOffset + len(string)
- self.eol = eol
- if label:
- self.label = label + ' '
- else:
- self.label = ''
- string = self.label + string
- cursorOffset += len(self.label)
- Region.__init__(self, string, cursorOffset, True)
- if not (self.contracted) and not (settings.disableBrailleEOL):
- self.string += self.eol
-
-
-
- def repositionCursor(self):
- '''Attempts to reposition the cursor in response to a new
- caret position. If it is possible (i.e., the caret is on
- the same line as it was), reposition the cursor and return
- True. Otherwise, return False.
- '''
- (string, caretOffset, lineOffset) = orca_state.activeScript.getTextLineAtCaret(self.accessible, self.startOffset)
- string = string.decode('UTF-8')
- cursorOffset = min(caretOffset - lineOffset, len(string))
- if lineOffset != self.lineOffset:
- return False
- self.caretOffset = caretOffset
- self.lineOffset = lineOffset
- cursorOffset += len(self.label)
- if self.contracted:
- (self.string, self.inPos, self.outPos, cursorOffset) = self.contractLine(self.rawLine, cursorOffset, True)
-
- self.cursorOffset = cursorOffset
- return True
-
-
- def processRoutingKey(self, offset):
- '''Processes a cursor routing key press on this Component. The offset
- is 0-based, where 0 represents the leftmost character of text
- associated with this region. Note that the zeroeth character may have
- been scrolled off the display.'''
- offset = self.displayToBufferOffset(offset)
- if offset < 0:
- return None
- newCaretOffset = min(self.lineOffset + offset, self._maxCaretOffset)
- orca_state.activeScript.setCaretOffset(self.accessible, newCaretOffset)
-
-
- def getAttributeMask(self, getLinkMask = True):
- """Creates a string which can be used as the attrOr field of brltty's
- write structure for the purpose of indicating text attributes, links,
- and selection.
-
- Arguments:
- - getLinkMask: Whether or not we should take the time to get
- the attributeMask for links. Reasons we might not want to
- include knowning that we will fail and/or it taking an
- unreasonable amount of time (AKA Gecko).
- """
-
- try:
- text = self.accessible.queryText()
- except NotImplementedError:
- return ''
-
- stringLength = len(self.rawLine) - len(self.label)
- lineEndOffset = self.lineOffset + stringLength
- regionMask = [
- settings.TEXT_ATTR_BRAILLE_NONE] * stringLength
- attrIndicator = settings.textAttributesBrailleIndicator
- selIndicator = settings.brailleSelectorIndicator
- linkIndicator = settings.brailleLinkIndicator
- script = orca_state.activeScript
- if getLinkMask and linkIndicator != settings.BRAILLE_LINK_NONE:
-
- try:
- hyperText = self.accessible.queryHypertext()
- nLinks = hyperText.getNLinks()
- except:
- nLinks = 0
-
- n = 0
- while n < nLinks:
- link = hyperText.getLink(n)
- if self.lineOffset <= link.startIndex:
- for i in xrange(link.startIndex, link.endIndex):
-
- try:
- regionMask[i] |= linkIndicator
- continue
- continue
-
-
-
- n += 1
-
- if attrIndicator:
- enabledAttributes = script.attribsToDictionary(settings.enabledBrailledTextAttributes)
- offset = self.lineOffset
- while offset < lineEndOffset:
- (attributes, startOffset, endOffset) = script.getTextAttributes(self.accessible, offset, True)
- if endOffset <= offset:
- break
-
- mask = settings.TEXT_ATTR_BRAILLE_NONE
- offset = endOffset
- for attrib in attributes:
- if enabledAttributes.get(attrib, '') != '':
- if enabledAttributes[attrib] != attributes[attrib]:
- mask = attrIndicator
- break
-
- enabledAttributes[attrib] != attributes[attrib]
-
- if mask != settings.TEXT_ATTR_BRAILLE_NONE:
- maskStart = max(startOffset - self.lineOffset, 0)
- maskEnd = min(endOffset - self.lineOffset, stringLength)
- for i in xrange(maskStart, maskEnd):
- regionMask[i] |= attrIndicator
-
-
- if selIndicator:
- selections = script.getTextSelections(self.accessible)
- for startOffset, endOffset in selections:
- maskStart = max(startOffset - self.lineOffset, 0)
- maskEnd = min(endOffset - self.lineOffset, stringLength)
- for i in xrange(maskStart, maskEnd):
- regionMask[i] |= selIndicator
-
-
-
- regionMask += [
- 0] * len(self.eol)
- if self.label:
- regionMask = [
- 0] * len(self.label) + regionMask
-
- return ''.join(map(chr, regionMask))
-
-
- def contractLine(self, line, cursorOffset = 0, expandOnCursor = True):
- (contracted, inPos, outPos, cursorPos) = Region.contractLine(self, line, cursorOffset, expandOnCursor)
- return (contracted + self.eol, inPos, outPos, cursorPos)
-
-
- def displayToBufferOffset(self, display_offset):
- offset = Region.displayToBufferOffset(self, display_offset)
- offset += self.startOffset
- offset -= len(self.label)
- return offset
-
-
- def setContractedBraille(self, contracted):
- Region.setContractedBraille(self, contracted)
- if not contracted:
- self.string += self.eol
-
-
-
-
- class ReviewComponent(Component):
- '''A subclass of Component that is to be used for flat review mode.'''
-
- def __init__(self, accessible, string, cursorOffset, zone):
- '''Creates a new Component.
-
- Arguments:
- - accessible: the accessible
- - string: the string to use to represent the component
- - cursorOffset: a 0-based index saying where to draw the cursor
- for this Region if it gets focus.
- - zone: the flat review Zone associated with this component
- '''
- Component.__init__(self, accessible, string, cursorOffset, expandOnCursor = True)
- self.zone = zone
-
-
-
- class ReviewText(Region):
- '''A subclass of Region backed by a Text object. This Region will
- does not react to the caret changes, but will react if one updates
- the cursorPosition. This class is meant to be used by flat review
- mode to show the current character position.
- '''
-
- def __init__(self, accessible, string, lineOffset, zone):
- '''Creates a new Text region.
-
- Arguments:
- - accessible: the accessible that implements AccessibleText
- - string: the string to use to represent the component
- - lineOffset: the character offset into where the text line starts
- - zone: the flat review Zone associated with this component
- '''
- Region.__init__(self, string, expandOnCursor = True)
- self.accessible = accessible
- self.lineOffset = lineOffset
- self.zone = zone
-
-
- def processRoutingKey(self, offset):
- '''Processes a cursor routing key press on this Component. The offset
- is 0-based, where 0 represents the leftmost character of text
- associated with this region. Note that the zeroeth character may have
- been scrolled off the display.'''
- offset = self.displayToBufferOffset(offset)
- newCaretOffset = self.lineOffset + offset
- orca_state.activeScript.setCaretOffset(self.accessible, newCaretOffset)
-
-
-
- class Line:
- '''A horizontal line on the display. Each Line is composed of a sequential
- set of Regions.
- '''
-
- def __init__(self, region = None):
- self.regions = []
- self.string = ''
- if region:
- self.addRegion(region)
-
-
-
- def addRegion(self, region):
- self.regions.append(region)
-
-
- def addRegions(self, regions):
- self.regions.extend(regions)
-
-
- def getLineInfo(self, getLinkMask = True):
- '''Computes the complete string for this line as well as a
- 0-based index where the focused region starts on this line.
- If the region with focus is not on this line, then the index
- will be -1.
-
- Arguments:
- - getLinkMask: Whether or not we should take the time to get
- the attributeMask for links. Reasons we might not want to
- include knowning that we will fail and/or it taking an
- unreasonable amount of time (AKA Gecko).
-
- Returns [string, offsetIndex, attributeMask]
- '''
- string = ''
- focusOffset = -1
- attributeMask = ''
- for region in self.regions:
- if region == _regionWithFocus:
- focusOffset = len(string)
-
- if region.string:
- string += region.string.replace(u'…', '...')
-
- mask = region.getAttributeMask(getLinkMask)
- attributeMask += mask
-
- return [
- string,
- focusOffset,
- attributeMask]
-
-
- def getRegionAtOffset(self, offset):
- '''Finds the Region at the given 0-based offset in this line.
-
- Returns the [region, offsetinregion] where the region is
- the region at the given offset, and offsetinregion is the
- 0-based offset from the beginning of the region, representing
- where in the region the given offset is.'''
- foundRegion = None
- string = ''
- pos = 0
- for region in self.regions:
- foundRegion = region
- string = string + region.string
- if len(string) > offset:
- break
- continue
- pos = len(string)
-
- if offset >= len(string):
- return [
- None,
- -1]
- return [
- foundRegion,
- offset - pos]
-
-
- def processRoutingKey(self, offset):
- '''Processes a cursor routing key press on this Component. The offset
- is 0-based, where 0 represents the leftmost character of string
- associated with this line. Note that the zeroeth character may have
- been scrolled off the display.'''
- (region, regionOffset) = self.getRegionAtOffset(offset)
- if region:
- region.processRoutingKey(regionOffset)
-
-
-
- def setContractedBraille(self, contracted):
- for region in self.regions:
- region.setContractedBraille(contracted)
-
-
-
-
- def getRegionAtCell(cell):
- """Given a 1-based cell offset, return the braille region
- associated with that cell in the form of [region, offsetinregion]
- where 'region' is the region associated with the cell and
- 'offsetinregion' is the 0-based offset of where the cell is
- in the region, where 0 represents the beginning of the region, """
- if len(_lines) > 0:
- offset = (cell - 1) + viewport[0]
- lineNum = viewport[1]
- return _lines[lineNum].getRegionAtOffset(offset)
- return [
- None,
- -1]
-
-
- def clear():
- '''Clears the logical structure, but keeps the Braille display as is
- (until a refresh operation).
- '''
- global _lines, _regionWithFocus, viewport
- _lines = []
- _regionWithFocus = None
- viewport = [
- 0,
- 0]
-
-
- def setLines(lines):
- global _lines
- _lines = lines
-
-
- def addLine(line):
- '''Adds a line to the logical display for painting. The line is added to
- the end of the current list of known lines. It is necessary for the
- viewport to be over the lines and for refresh to be called for the new
- line to be painted.
-
- Arguments:
- - line: an instance of Line to add.
- '''
- _lines.append(line)
- line._index = len(_lines)
-
-
- def getShowingLine():
- '''Returns the Line that is currently being painted on the display.
- '''
- return _lines[viewport[1]]
-
-
- def setFocus(region, panToFocus = True, getLinkMask = True):
- '''Specififes the region with focus. This region will be positioned
- at the home position if panToFocus is True.
-
- Arguments:
- - region: the given region, which much be in a line that has been
- added to the logical display
- - panToFocus: whether or not to position the region at the home
- position
- - getLinkMask: Whether or not we should take the time to get the
- attributeMask for links. Reasons we might not want to include
- knowning that we will fail and/or it taking an unreasonable
- amount of time (AKA Gecko).
- '''
- global _regionWithFocus
- _regionWithFocus = region
- if not panToFocus or not _regionWithFocus:
- return None
- lineNum = 0
- done = False
- for line in _lines:
- for reg in line.regions:
- if reg == _regionWithFocus:
- viewport[1] = lineNum
- done = True
- break
- continue
- not _regionWithFocus
-
- if done:
- break
- continue
- lineNum += 1
-
- line = _lines[viewport[1]]
- (string, offset, attributeMask) = line.getLineInfo(getLinkMask)
- if _regionWithFocus.cursorOffset >= _displaySize[0]:
- offset += (_regionWithFocus.cursorOffset - _displaySize[0]) + 1
-
- viewport[0] = max(0, offset)
-
-
- def refresh(panToCursor = True, targetCursorCell = 0, getLinkMask = True):
- """Repaints the Braille on the physical display. This clips the entire
- logical structure by the viewport and also sets the cursor to the
- appropriate location. [[[TODO: WDW - I'm not sure how BrlTTY handles
- drawing to displays with more than one line, so I'm only going to handle
- drawing one line right now.]]]
-
- Arguments:
-
- - panToCursor: if True, will adjust the viewport so the cursor is
- showing.
- - targetCursorCell: Only effective if panToCursor is True.
- 0 means automatically place the cursor somewhere on the display so
- as to minimize movement but show as much of the line as possible.
- A positive value is a 1-based target cell from the left side of
- the display and a negative value is a 1-based target cell from the
- right side of the display.
- - getLinkMask: Whether or not we should take the time to get the
- attributeMask for links. Reasons we might not want to include
- knowning that we will fail and/or it taking an unreasonable
- amount of time (AKA Gecko).
- """
- global cursorCell, cursorCell, cursorCell, monitor, monitor, beginningIsShowing, endIsShowing
- if len(_lines) == 0:
- if useBrlAPIBindings:
- if brlAPIRunning:
- brlAPI.writeText('', 0)
-
- else:
- brl.writeText(0, '')
- return None
- if targetCursorCell < 0:
- targetCursorCell = _displaySize[0] + targetCursorCell + 1
-
- line = _lines[viewport[1]]
- (string, focusOffset, attributeMask) = line.getLineInfo(getLinkMask)
- cursorOffset = -1
- if focusOffset >= 0:
- cursorOffset = focusOffset + _regionWithFocus.cursorOffset
-
- if panToCursor and cursorOffset >= 0:
- if len(string) <= _displaySize[0]:
- viewport[0] = 0
- elif targetCursorCell:
- viewport[0] = max(0, (cursorOffset - targetCursorCell) + 1)
- elif cursorOffset < viewport[0]:
- viewport[0] = max(0, cursorOffset)
- elif cursorOffset >= viewport[0] + _displaySize[0]:
- viewport[0] = max(0, (cursorOffset - _displaySize[0]) + 1)
-
-
- startPos = viewport[0]
- endPos = startPos + _displaySize[0]
- cursorCell = cursorOffset - startPos
- if cursorCell < 0 or cursorCell >= _displaySize[0]:
- cursorCell = 0
- else:
- cursorCell += 1
- logLine = "BRAILLE LINE: '%s'" % string
- debug.println(debug.LEVEL_INFO, logLine)
- log.info(logLine.encode('UTF-8'))
- logLine = " VISIBLE: '%s', cursor=%d" % (string[startPos:endPos], cursorCell)
- debug.println(debug.LEVEL_INFO, logLine)
- log.info(logLine.encode('UTF-8'))
- substring = string[startPos:endPos]
- if useBrlAPIBindings:
- if brlAPIRunning:
- writeStruct = brlapi.WriteStruct()
- writeStruct.regionBegin = 1
- writeStruct.regionSize = len(substring)
- while writeStruct.regionSize < _displaySize[0]:
- substring += ' '
- if attributeMask:
- attributeMask += '\x00'
-
- writeStruct.regionSize += 1
- continue
- writeStruct
- writeStruct.text = substring
- writeStruct.cursor = cursorCell
- if attributeMask:
- writeStruct.attrOr = attributeMask[startPos:endPos]
-
- brlAPI.write(writeStruct)
-
- else:
- brl.writeText(cursorCell, substring)
- if settings.enableBrailleMonitor:
- if not monitor:
- monitor = brlmon.BrlMon(_displaySize[0])
- monitor.show_all()
-
- if attributeMask:
- subMask = attributeMask[startPos:endPos]
- else:
- subMask = None
- monitor.writeText(cursorCell, substring, subMask)
- elif monitor:
- monitor.destroy()
- monitor = None
-
- beginningIsShowing = startPos == 0
- endIsShowing = endPos >= len(string)
-
-
- def displayRegions(regionInfo):
- '''Displays a list of regions on a single line, setting focus to the
- specified region. The regionInfo parameter is something that is
- typically returned by a call to braillegenerator.getBrailleRegions.
-
- Arguments:
- - regionInfo: a list where the first element is a list of regions
- to display and the second element is the region
- with focus (must be in the list from element 0)
- '''
- regions = regionInfo[0]
- focusedRegion = regionInfo[1]
- clear()
- line = Line()
- for item in regions:
- line.addRegion(item)
-
- addLine(line)
- setFocus(focusedRegion)
- refresh()
-
-
- def displayMessage(message, cursor = -1):
- '''Displays a single line, setting the cursor to the given position,
- ensuring that the cursor is in view.
-
- Arguments:
- - message: the string to display
- - cursor: the 0-based cursor position, where -1 (default) means no cursor
- '''
- clear()
- region = Region(message, cursor)
- addLine(Line(region))
- setFocus(region)
- refresh(True)
-
-
- def panLeft(panAmount = 0):
- '''Pans the display to the left, limiting the pan to the beginning
- of the line being displayed.
-
- Arguments:
- - panAmount: the amount to pan. A value of 0 means the entire
- width of the physical display.
-
- Returns True if a pan actually happened.
- '''
- oldX = viewport[0]
- if panAmount == 0:
- panAmount = _displaySize[0]
-
- if viewport[0] > 0:
- viewport[0] = max(0, viewport[0] - panAmount)
-
- return oldX != viewport[0]
-
-
- def panRight(panAmount = 0):
- '''Pans the display to the right, limiting the pan to the length
- of the line being displayed.
-
- Arguments:
- - panAmount: the amount to pan. A value of 0 means the entire
- width of the physical display.
-
- Returns True if a pan actually happened.
- '''
- oldX = viewport[0]
- if panAmount == 0:
- panAmount = _displaySize[0]
-
- if len(_lines) > 0:
- lineNum = viewport[1]
- newX = viewport[0] + panAmount
- (string, focusOffset, attributeMask) = _lines[lineNum].getLineInfo()
- if newX < len(string):
- viewport[0] = newX
-
-
- return oldX != viewport[0]
-
-
- def panToOffset(offset):
- '''Automatically pan left or right to make sure the current offset is
- showing.'''
- while offset < viewport[0]:
- debug.println(debug.LEVEL_FINEST, 'braille.panToOffset (left) %d' % offset)
- if not panLeft():
- break
- continue
- while offset >= viewport[0] + _displaySize[0]:
- debug.println(debug.LEVEL_FINEST, 'braille.panToOffset (right) %d' % offset)
- if not panRight():
- break
- continue
-
-
- def returnToRegionWithFocus(inputEvent = None):
- '''Pans the display so the region with focus is displayed.
-
- Arguments:
- - inputEvent: the InputEvent instance that caused this to be called.
-
- Returns True to mean the command should be consumed.
- '''
- setFocus(_regionWithFocus)
- refresh(True)
- return True
-
-
- def _processBrailleEvent(command):
- '''Handles BrlTTY command events. This passes commands on to Orca for
- processing. If Orca does not handle them (as indicated by a return value
- of false from the callback passed to init, it will attempt to handle the
- command itself - either by panning the viewport or passing cursor routing
- keys to the Regions for handling.
-
- Arguments:
- - command: the BrlAPI command for the key that was pressed.
- '''
- _printBrailleEvent(debug.LEVEL_FINE, command)
- if command & BRL_FLG_REPEAT_INITIAL:
- command &= ~(BRL_FLG_REPEAT_INITIAL | BRL_FLG_REPEAT_DELAY)
- elif command & BRL_FLG_REPEAT_DELAY:
- return True
- consumed = False
- if settings.timeoutCallback and settings.timeoutTime > 0:
- signal.signal(signal.SIGALRM, settings.timeoutCallback)
- signal.alarm(settings.timeoutTime)
-
- if _callback:
-
- try:
- consumed = _callback(command)
- debug.printException(debug.LEVEL_WARNING)
- consumed = False
-
-
- if command >= 256 and command < 256 + _displaySize[0]:
- if len(_lines) > 0:
- cursor = (command - 256) + viewport[0]
- lineNum = viewport[1]
- _lines[lineNum].processRoutingKey(cursor)
- consumed = True
-
-
- if command in (8513, 65):
- settings.enableContractedBraille = not (settings.enableContractedBraille)
- for line in _lines:
- line.setContractedBraille(settings.enableContractedBraille)
-
- refresh()
-
- if settings.timeoutCallback and settings.timeoutTime > 0:
- signal.alarm(0)
-
- return consumed
-
-
- def _brlAPIKeyReader(source, condition):
- '''Method to read a key from the BrlAPI bindings. This is a
- gobject IO watch handler.
- '''
- key = brlAPI.readKey(False)
- if key:
- lower = key & 0xFFFFFFFFL
- keyCode = lower & 536870911
- if keyCode & 65536:
- keyCode = 256 | keyCode & 255
-
- if keyCode:
- _processBrailleEvent(keyCode)
-
-
- return brlAPIRunning
-
-
- def setupKeyRanges(keys):
- '''Hacky method to tell BrlTTY what to send and not send us via
- the readKey method. This only works with BrlTTY v3.8 and better.
-
- Arguments:
- -keys: a list of BrlAPI commands.
- '''
- if not brlAPIRunning:
- return None
-
- try:
- brlAPI.ignoreKeys(brlapi.rangeType_all, [
- 0])
- keySet = [
- brlapi.KEY_TYPE_CMD | brlapi.KEY_CMD_ROUTE]
- for key in keys:
- keySet.append(brlapi.KEY_TYPE_CMD | key)
-
- brlAPI.acceptKeys(brlapi.rangeType_command, keySet)
- brlAPI.acceptKeys(brlapi.rangeType_key, [
- 65])
- debug.println(debug.LEVEL_FINEST, 'Using BrlAPI v0.5.0+')
- except:
- brlAPIRunning
- debug.printException(debug.LEVEL_FINEST)
-
- try:
- brlAPI.ignoreKeyRange(0, brlapi.KEY_FLAGS_MASK | brlapi.KEY_TYPE_MASK | brlapi.KEY_CODE_MASK)
- brlAPI.acceptKeyRange(brlapi.KEY_TYPE_CMD | brlapi.KEY_CMD_ROUTE, brlapi.KEY_TYPE_CMD | brlapi.KEY_CMD_ROUTE | brlapi.KEY_CMD_ARG_MASK)
- keySet = []
- for key in keys:
- keySet.append(brlapi.KEY_TYPE_CMD | key)
-
- if len(keySet):
- brlAPI.acceptKeySet(keySet)
-
- debug.println(debug.LEVEL_FINEST, 'Using BrlAPI pre-release v0.5.0')
- debug.printException(debug.LEVEL_FINEST)
- debug.println(debug.LEVEL_WARNING, 'Braille module cannot listen for braille input events')
-
-
-
-
- def init(callback = None, tty = 7):
- '''Initializes the braille module, connecting to the BrlTTY driver.
-
- Arguments:
- - callback: the method to call with a BrlTTY input event.
- - tty: the tty port to take ownership of (default = 7)
- Returns True if the initialization procedure was run or False if this
- module has already been initialized.
- '''
- global _callback, brlAPI, brlAPIRunning, brlAPIRunning, brlAPISourceId, _displaySize, _displaySize, _initialized
- if _initialized:
- return False
- _callback = callback
- if useBrlAPIBindings:
-
- try:
- gobject.threads_init()
- brlAPI = brlapi.Connection()
-
- try:
- import os
- windowPath = os.environ['WINDOWPATH']
- brlAPI.enterTtyModeWithPath()
- brlAPIRunning = True
- debug.println(debug.LEVEL_CONFIGURATION, 'Braille module has been initialized using WINDOWPATH=' + '%s' % windowPath)
- except:
- _initialized
- brlAPI.enterTtyMode(tty)
- brlAPIRunning = True
- debug.println(debug.LEVEL_CONFIGURATION, 'Braille module has been initialized using tty=%d' % tty)
-
- brlAPISourceId = gobject.io_add_watch(brlAPI.fileDescriptor, gobject.IO_IN, _brlAPIKeyReader)
- debug.printException(debug.LEVEL_FINEST)
- return False
-
- elif brl.init(tty):
- debug.println(debug.LEVEL_CONFIGURATION, 'Braille module has been initialized.')
- brl.registerCallback(_processBrailleEvent)
- else:
- debug.println(debug.LEVEL_CONFIGURATION, 'Braille module has NOT been initialized.')
- return False
- if _initialized:
- (x, y) = brlAPI.displaySize
- _displaySize = [
- x,
- 1]
- else:
- _displaySize = [
- brl.getDisplayWidth(),
- 1]
- debug.println(debug.LEVEL_CONFIGURATION, 'braille display size = (%d, %d)' % (_displaySize[0], _displaySize[1]))
- clear()
- refresh(True)
- _initialized = True
- return True
-
-
- def shutdown():
- '''Shuts down the braille module. Returns True if the shutdown procedure
- was run or False if this module has not been initialized.
- '''
- global brlAPIRunning, brlAPISourceId, _initialized
- if not _initialized:
- return False
- if useBrlAPIBindings:
- if brlAPIRunning:
- brlAPIRunning = False
- gobject.source_remove(brlAPISourceId)
- brlAPISourceId = 0
- brlAPI.leaveTtyMode()
-
- else:
- brl.shutdown()
- _initialized = False
- return True
-
-